/*
 *  javaFilter.c
 *  CorP5e
 *
 *  Created by Matthew Giant on 9/27/09.
 *  Copyright 2009 __MyCompanyName__. All rights reserved.
 *
 */

#import "javaFilter.h"

#import "CorP5eSession.h"
#import "CorP5eFilter.h"
#import "jniutil.h"

#import <JavaVM/jni.h>

JNIEXPORT jlong JNICALL
Java_com_mattgiant_corP5e_CorP5eSession_00024CIFilter_alloc(	JNIEnv	*env, 
																jobject obj,
																jstring jFilterName )
{
	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

	NSString *filterName = JavaStringToNSString( env, jFilterName );
	//convert java filter name string to c string
	
	NSLog( @"filter name %@", filterName );
	
	jlong filterId = [[CorP5eSession instance] createFilter:filterName];
	
	[pool drain];
	
	return filterId;
}

JNIEXPORT void JNICALL
Java_com_mattgiant_corP5e_CorP5eSession_00024CIFilter_dealloc(	JNIEnv	*env, 
																jobject obj,
																jlong	filterId )
{
	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
		//alloc autorelease pool to be used for the duration of this call
	
	[[CorP5eSession instance] removeObjectWithId:filterId];
		//fetch previously created flter from session
	[pool release];

}


JNIEXPORT jint JNICALL 
Java_com_mattgiant_corP5e_CorP5eSession_00024CIFilter_setImageValueInt(	JNIEnv		*env, 
																		jobject		obj,
																		jlong		filterId,
																		jint		key,
																		jint		pixelFormat,
																		jint		width,
																		jint		height,
																		jintArray	pixels )
{
	int res = 0;
	
	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

	//get native array of pixel data
	NSString *keyName = jintToFilterConstant( key );
	
	jboolean pixelsIsCopy;

	jint *pixelData = (*env)->GetIntArrayElements(	env,
													pixels, 
													&pixelsIsCopy );
	
	CIImage *img = [[CorP5eSession instance] makeCIImageWithFormat:pixelFormat
														   width:width
														  height:height 
														  pixels:(UInt32 *)pixelData];
	
	
	(*env)->ReleaseIntArrayElements(	env,
										pixels, 
										pixelData, 
										0 );
		//release native version of pixel data
	
	//make sure image was created
	if ( !img )
	{
		res = -1;
	}
	else 
	{
		CorP5eFilter *filter = [[CorP5eSession instance] filterWithId:filterId];
		//fetch previously created flter from session
	
		//make sure filter was found
		if ( !filter )
		{
			res = -1;
		}
		else
		{
			[filter setFilterValueWithKey:keyName withImage:img];
		}
	}

	
	[pool drain];
	
	return res;
}

JNIEXPORT jint JNICALL 
Java_com_mattgiant_corP5e_CorP5eSession_00024CIFilter_setImageValueString(	JNIEnv		*env, 
																			jobject		obj,
																			jlong		filterId,
																			jstring		jKeyName,
																			jint		pixelFormat,
																			jint		width,
																			jint		height,
																			jintArray	pixels )
{
	int res = 0;
	
	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
		//alloc autorelease pool to be used for the duration of this call

	NSString *keyName = JavaStringToNSString( env, jKeyName );
		//convert java parameter name string to c string

	jboolean pixelsIsCopy;
	
	jint *pixelData = (*env)->GetIntArrayElements(	env,
													pixels, 
													&pixelsIsCopy );
	
	CIImage *img = [[CorP5eSession instance] makeCIImageWithFormat:pixelFormat
														   width:width
														  height:height 
														  pixels:(UInt32 *)pixelData];
	
	
	(*env)->ReleaseIntArrayElements(	env,
										pixels, 
										pixelData, 
										0 );
		//release native version of pixel data
	
	
	//make sure image was created
	if ( !img )
	{
		res = -1;
	}
	else
	{
		CorP5eFilter *filter = [[CorP5eSession instance] filterWithId:filterId];
			//fetch previously created flter from session
	
		//make sure filter was found
		if ( !filter )
		{
			res = -1;
		}
		else
		{
			[filter setFilterValueWithKey:keyName withImage:img];
		}
	}

	[pool drain];
	
	return res;
}

JNIEXPORT jint JNICALL
Java_com_mattgiant_corP5e_CorP5eSession_00024CIFilter_setFloatValueString(	JNIEnv	*env,
																			jobject obj,
																			jlong	filterId,
																			jstring	key,
																			jfloat	value )
{
	int res = 0;
	
	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
		//alloc autorelease pool to be used for the duration of this call

	NSString *keyName = JavaStringToNSString( env, key );
	
	CorP5eFilter *filter = [[CorP5eSession instance] filterWithId:filterId];
		//fetch previously created flter from session
	
	//make sure filter was found
	if ( !filter )
	{
		res = -1;
	}
	else 
	{
		[filter setFilterValueWithKey:keyName withFloat:value];
	}
	
	[pool drain];
	
	return res;
}

JNIEXPORT jint JNICALL 
Java_com_mattgiant_corP5e_CorP5eSession_00024CIFilter_setValueParamInt(	JNIEnv	*env,
																		jobject obj,
																		jlong	filterId,
																		jint	key,
																		jfloat	value )
{
	int res = 0;
	
	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
	
	NSString *keyName = jintToFilterConstant( key );
	
	CorP5eFilter *filter = [[CorP5eSession instance] filterWithId:filterId];
	//fetch previously created flter from session
	
	//make sure filter was found
	if ( !filter )
	{
		res = -1;
	}
	else
	{
		[filter setFilterValueWithKey:keyName withFloat:value];
	}
	
	[pool drain];
	
	return res;
}

JNIEXPORT jint JNICALL 
Java_com_mattgiant_corP5e_CorP5eSession_00024CIFilter_setVectorValueInt(	JNIEnv	*env,
																			jobject obj,
																			jlong	filterId,
																			jint	key,
																			jfloat	x,
																			jfloat	y,
																			jfloat	z,
																			jfloat	w )
{
	int res = 0;
	
	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
		//alloc autorelease pool to be used for the duration of this call
	
	NSString *keyName = jintToFilterConstant( key );
	
	CorP5eFilter *filter = [[CorP5eSession instance] filterWithId:filterId];
		//fetch previously created flter from session
	
	//make sure filter was found
	if ( !filter )
	{
		res = -1;
	}
	else 
	{
		[filter setFilterValueWithKey:keyName 
						   withVector:[CIVector vectorWithX:x 
														  Y:y
														  Z:z
														  W:w]];
			//store image as param on filter
	}
	
	[pool drain];
		//free non-retained autorelease objects
	
	return res;
}

JNIEXPORT jint JNICALL 
Java_com_mattgiant_corP5e_CorP5eSession_00024CIFilter_setVectorValueString(	JNIEnv	*env,
																			jobject obj,
																			jlong	filterId,
																			jstring	key,
																			jfloat	x,
																			jfloat	y,
																			jfloat	z,
																			jfloat	w )
{
	int res = 0;
	
	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
	
	NSString *keyName = JavaStringToNSString( env, key );
	
	CorP5eFilter *filter = [[CorP5eSession instance] filterWithId:filterId];
	//fetch previously created flter from session
	
	//make sure filter was found
	if ( !filter )
	{
		res = -1;
	}
	else
	{
		[filter setFilterValueWithKey:keyName 
						   withVector:[CIVector vectorWithX:x 
														  Y:y
														  Z:z	
														  W:w]];
	}
	
	[pool drain];
	
	return res;
}

JNIEXPORT jint JNICALL 
Java_com_mattgiant_corP5e_CorP5eSession_00024CIFilter_getImageForKey(	JNIEnv		*env,
																		jobject		obj,
																		jlong		filterId,
																		jstring		key,
																		jobject		outImg,
																		jboolean	preserveSize )
{
	jint res = 0;

	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
		//alloc autorelease pool to be used for the duration of this call
		
	NSString *keyName = JavaStringToNSString( env, key );
	
	jclass pImgCls = (*env)->GetObjectClass( env, outImg );
		//get Class object for PImage
	
	//look up field id values for fields that need to be set
	jfieldID widthField		= (*env)->GetFieldID( env, pImgCls, "width", "I" );
	jfieldID heightField	= (*env)->GetFieldID( env, pImgCls, "height", "I" );
	jfieldID pixelsField	= (*env)->GetFieldID( env, pImgCls, "pixels", "[I" );

	CorP5eFilter *filter = [[CorP5eSession instance] filterWithId:filterId];
		//fetch previously created flter from session
	
	//make sure filter was found
	if ( !filter )
	{
		res = -1;
	}
	else
	{
		CIImage *img = [filter getFilterValueForKey:keyName];
			//[img retain];
	
		int x = 0;
		int y = 0;
		int width  = 0;
		int height = 0;
		
		jintArray pixelArray;
		
		if ( preserveSize )
		{
			width  = (*env)->GetIntField( env, outImg, widthField );
			height = (*env)->GetIntField( env, outImg, heightField );
			
			pixelArray = (*env)->GetObjectField( env, outImg, pixelsField );
		}
		else 
		{
			CGRect ext = [img extent];
			width  = ext.size.width;
			height = ext.size.height;

			x = ext.origin.x;
			y = ext.origin.y;
			
			//store width and height in PImage object
			(*env)->SetIntField( env, outImg, widthField,	width );
			(*env)->SetIntField( env, outImg, heightField,	height );

			jsize nPixels = width * height;
			
			jintArray pixelArray = (*env)->NewIntArray( env, nPixels );
			
			(*env)->SetObjectField( env, outImg, pixelsField, pixelArray );
				//set pixels member of PImage to new pixel array
		}
		
		jboolean isCopy;
		jint *pixels = (*env)->GetIntArrayElements( env, pixelArray, &isCopy );

		[[CorP5eSession instance] renderImage:img
										 rect:CGRectMake( x, y, width, height ) 
									 toBuffer:pixels];
			
		(*env)->ReleaseIntArrayElements( env, pixelArray, pixels, 0 );
	}
	
	[pool release];
	
	return res;
}

JNIEXPORT jint JNICALL 
Java_com_mattgiant_corP5e_CorP5eSession_00024CIFilter_setColorValueString(	JNIEnv	*env,
																			jobject obj,
																			jlong	filterId,
																			jstring	key,
																			jfloat	r,
																			jfloat	g,
																			jfloat	b,
																			jfloat	a )
{
	int res = 0;
	
	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
	
	NSString *keyName = JavaStringToNSString( env, key );
	
	CorP5eFilter *filter = [[CorP5eSession instance] filterWithId:filterId];
	//fetch previously created flter from session
	
	//make sure filter was found
	if ( !filter )
	{
		res = -1;
	}
	else
	{
		[filter setFilterValueWithKey:keyName 
							withColor:[CIColor colorWithRed:r green:g blue:b alpha:a]];
	}
	
	[pool drain];
	
	return res;
}

JNIEXPORT jint JNICALL 
Java_com_mattgiant_corP5e_CorP5eSession_00024CIFilter_setColorValueInt(	JNIEnv	*env,
																		jobject obj,
																		jlong	filterId,
																		jint	key,
																		jfloat	r,
																		jfloat	g,
																		jfloat	b,
																		jfloat	a )
{
	int res = 0;
	
	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
	//alloc autorelease pool to be used for the duration of this call
	
	NSString *keyName = jintToFilterConstant( key );
	
	CorP5eFilter *filter = [[CorP5eSession instance] filterWithId:filterId];
	//fetch previously created flter from session
	
	//make sure filter was found
	if ( !filter )
	{
		res = -1;
	}
	else 
	{
		[filter setFilterValueWithKey:keyName 
						   withColor:[CIColor colorWithRed:r green:g blue:b alpha:a]];
		//store image as param on filter
	}
	
	[pool drain];
	//free non-retained autorelease objects
	
	return res;
}